home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / nr4user.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  5KB  |  202 lines

  1. /* net/rom level 4 (transport) protocol user level calls
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.  
  16. #undef NR4DEBUG
  17.  
  18. /* Open a NET/ROM transport connection */
  19. struct nr4cb *
  20. open_nr4(node,user,r_upcall,t_upcall,s_upcall,puser)
  21. struct ax25_addr *node ;    /* destination node address */
  22. struct ax25_addr *user ;    /* local ax25 user callsign */
  23. void (*r_upcall)() ;        /* received data upcall */
  24. void (*t_upcall)() ;        /* transmit upcall */
  25. void (*s_upcall)() ;        /* state change upcall */
  26. char *puser ;                /* pointer to upper level control block */
  27. {
  28.     struct nr4cb *cb ;
  29.     struct nr4hdr hdr ;
  30.  
  31.     if ((cb = new_n4circ()) == NULLNR4CB)
  32.         return NULLNR4CB ;        /* No circuits available */
  33.  
  34.     /* Stuff what info we can into control block */
  35.  
  36.     cb->user = *node ;        /* When we initiate, user is remote node */
  37.     cb->node = *node ;
  38.     cb->luser = *user ;        /* Save local user for connect retries */
  39.     cb->r_upcall = r_upcall ;
  40.     cb->t_upcall = t_upcall ;
  41.     cb->s_upcall = s_upcall ;
  42.     cb->puser = puser ;
  43.  
  44.     /* Format connect request header */
  45.  
  46.     hdr.opcode = NR4OPCONRQ ;
  47.     hdr.u.conreq.myindex = cb->mynum ;
  48.     hdr.u.conreq.myid = cb->myid ;
  49.     hdr.u.conreq.window = Nr4window ;
  50.     hdr.u.conreq.user = *user ;
  51.  
  52.     /* The choice of mycall here is suspect.  If I have a unique */
  53.     /* callsign per interface, then a layer violation will be */
  54.     /* required to determine the "real" callsign for my (virtual) */
  55.     /* node.  This suggests that callsign-per-interface is not */
  56.     /* desirable, which answers *that* particular open question. */
  57.     
  58.     hdr.u.conreq.node = mycall ;
  59.  
  60.     /* Set and start connection retry timer */
  61.  
  62.     cb->cdtries = 1 ;
  63.     cb->srtt = Nr4irtt ;
  64.     cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  65.     cb->tcd.func = nr4cdtimeout ;
  66.     cb->tcd.arg = (char *)cb ;
  67.     start_timer(&cb->tcd) ;
  68.     
  69.     /* Send connect request packet */
  70.  
  71.     nr4sframe(node, &hdr, NULLBUF) ;
  72.  
  73.     /* Set up initial state and signal state change */
  74.  
  75.     cb->state = NR4STDISC ;
  76.     nr4state(cb, NR4STCPEND) ;
  77.  
  78.     /* Return control block address */
  79.  
  80.     return cb ;
  81. }
  82.  
  83. /* Send a net/rom transport data packet */
  84. int
  85. send_nr4(cb,bp)
  86. struct nr4cb *cb ;
  87. struct mbuf *bp ;
  88. {
  89.     if (cb == NULLNR4CB || bp == NULLBUF)
  90.         return -1 ;
  91.     enqueue(&cb->txq,bp) ;
  92.     return nr4output(cb) ;
  93. }
  94.  
  95. /* Receive incoming net/rom transport data */
  96. /*ARGSUSED*/
  97. struct mbuf *
  98. recv_nr4(cb,cnt)
  99. struct nr4cb *cb ;
  100. int16 cnt ;
  101. {
  102.     struct mbuf *bp ;
  103.  
  104.     if (cb->rxq == NULLBUF)
  105.         return NULLBUF ;
  106.  
  107.     bp = cb->rxq ;            /* Just give `em everything */
  108.     cb->rxq = NULLBUF ;
  109.  
  110.     /* Since we took everything, we always go unchoked.  If we */
  111.     /* ever change this code to use cnt, or make it a real packet */
  112.     /* delivery, there will have to be a check to see if the queue */
  113.     /* has gotten short enough yet. */
  114.  
  115.     if (cb->qfull) {
  116.         cb->qfull = 0 ;                /* Choke flag off */
  117.         nr4ackit((char *)cb) ;        /* Get things rolling again */
  118.     }
  119.  
  120.     return bp ;
  121. }
  122.  
  123. /* Close a NET/ROM connection */
  124. void
  125. disc_nr4(cb)
  126. struct nr4cb *cb ;
  127. {
  128.     struct nr4hdr hdr ;
  129.     
  130.     if (cb->state != NR4STCON)
  131.         return ;
  132.  
  133.     /* Format disconnect request packet */
  134.     
  135.     hdr.opcode = NR4OPDISRQ ;
  136.     hdr.yourindex = cb->yournum ;
  137.     hdr.yourid = cb->yourid ;
  138.  
  139.     /* Set and start timer */
  140.     
  141.     cb->cdtries = 1 ;
  142.     cb->tcd.start = (2 * cb->srtt) / MSPTICK ;
  143.     cb->tcd.func = nr4cdtimeout ;
  144.     cb->tcd.arg = (char *)cb ;
  145.     start_timer(&cb->tcd) ;
  146.  
  147.     /* Send packet */
  148.  
  149.     nr4sframe(&cb->node, &hdr, NULLBUF) ;
  150.  
  151.     /* Signal state change.  nr4state will take care of stopping */
  152.     /* the appropriate timers and resetting window pointers. */
  153.  
  154.     nr4state(cb, NR4STDPEND) ;
  155.     
  156. }
  157.  
  158. /* Abruptly terminate a NET/ROM transport connection */
  159. void
  160. reset_nr4(cb)
  161. struct nr4cb *cb ;
  162. {
  163.     cb->dreason = NR4RRESET ;
  164.     nr4state(cb,NR4STDISC) ;
  165. }
  166.  
  167.  
  168. /* Force retransmission on a NET/ROM transport connection */
  169. int
  170. kick_nr4(cb)
  171. struct nr4cb *cb ;
  172. {
  173.     unsigned seq ;
  174.     struct timer *t ;
  175.  
  176.     if(!nr4valcb(cb))
  177.         return -1 ;
  178.  
  179.     switch (cb->state) {
  180.       case NR4STCPEND:
  181.       case NR4STDPEND:
  182.           stop_timer(&cb->tcd) ;
  183.         nr4cdtimeout((char *)cb) ;
  184.         break ;
  185.  
  186.       case NR4STCON:
  187.         if (cb->nextosend != cb->ackxpected) {    /* if send window is open: */
  188.             for (seq = cb->ackxpected ;
  189.                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  190.                  seq = (seq + 1) & NR4SEQMASK) {
  191.                 t = &cb->txbufs[seq % cb->window].tretry ;
  192.                 stop_timer(t) ;
  193.                 t->state = TIMER_EXPIRE ;    /* fool retry routine */
  194.             }
  195.             nr4txtimeout((char *)cb) ;
  196.         }
  197.         break ;
  198.     }
  199.  
  200.     return 0 ;
  201. }
  202.